#include "cc_sem.h"
#include "cc_log.h"
void cc_sem_init(cc_sem_t sem, uint32_t init, uint32_t max)
{
  if (sem == CC_NULL)
  {
    cc_log_e("sem is null\r\n");
    return;
  }
  (void)xSemaphoreCreateCountingStatic(max, init, &sem->sem);
}

cc_sem_t cc_sem_create(int init, int max)
{
  cc_sem_t sem = (cc_sem_t)cc_malloc(sizeof(cc_sem));
  if (sem)
  {
    cc_log_e("sem is null\r\n");
    return CC_NULL;
  }
  cc_sem_init(sem, init, max);
  return sem;
}

int cc_sem_release(cc_sem_t sem)
{
  if (sem == CC_NULL)
  {
    cc_log_e("sem is null\r\n");
    return CC_ENOMEM;
  }
  if (cc_is_in_isr())
  {
    BaseType_t xHigherPriorityTaskWoken;
    int status = xSemaphoreGiveFromISR((SemaphoreHandle_t)&sem->sem, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    return status;
  }
  return xSemaphoreGive((SemaphoreHandle_t)&sem->sem);
}

int cc_sem_wait(cc_sem_t sem)
{
  return cc_sem_wait_time(sem, CC_TIME_WAIT_FOREVER);
}

int cc_sem_try_wait(cc_sem_t sem)
{
  return cc_sem_wait_time(sem, 0);
}

int cc_sem_wait_time(cc_sem_t sem, uint32_t ms)
{
  if (sem == CC_NULL)
  {
    cc_log_e("sem is null\r\n");
    return CC_ENOMEM;
  }
  if (cc_is_in_isr())
  {
    BaseType_t xHigherPriorityTaskWoken;
    int status = xSemaphoreTakeFromISR((SemaphoreHandle_t)&sem->sem, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    return status;
  }
  return xSemaphoreTake((SemaphoreHandle_t)&sem->sem, ms);
}

int cc_sem_get_cnt(cc_sem_t sem)
{
  if (sem == CC_NULL)
  {
    cc_log_e("sem is null\r\n");
    return CC_ENOMEM;
  }
  return uxSemaphoreGetCount((SemaphoreHandle_t)&sem->sem);
}

void cc_sem_deinit(cc_sem_t sem)
{
  if (sem == CC_NULL)
  {
    cc_log_e("sem is null\r\n");
    return;
  }
  return vSemaphoreDelete((SemaphoreHandle_t)&sem->sem);
}

void cc_sem_destory(cc_sem_t sem)
{
  if (sem == CC_NULL)
  {
    cc_log_e("sem is null\r\n");
    return;
  }
  cc_sem_deinit(sem);
  cc_free(sem);
}